<template>
  <div class="app-container">
    <el-row>
      <el-col :span="4">
        <div class="category-tree">
          物料分类信息
        </div>
        <el-divider><i class="el-icon-coffee-cup" /></el-divider>
        <el-tree :data="categoryTree" :props="defaultProps" :highlight-current="true" @node-click="handleNodeClick" />
      </el-col>
      <el-col :span="20">
        <!-- 过滤 -->
        <div class="filter-container">
          <el-input v-model="listQuery.materialEncoding" placeholder="物料编码" style="width: 200px;" class="filter-item" />
          <el-input v-model="listQuery.materialName" placeholder="物料名称" style="width: 200px;" class="filter-item" />
          <el-input v-model="listQuery.version" placeholder="型号" style="width: 200px;" class="filter-item" />
          <el-input v-model="listQuery.standard" placeholder="规格" style="width: 200px;" class="filter-item" />
          <el-input v-model="listQuery.unit" placeholder="单位" style="width: 200px;" class="filter-item" />
          <el-input v-model="listQuery.price" placeholder="单价" style="width: 200px;" class="filter-item" />
          <el-select v-model="listQuery.type" default-first-option placeholder="类型" clearable class="filter-item" style="width: 130px">
            <el-option v-for="item in type" :key="item.key" :label="item.label" :value="item.key" />
          </el-select>
          <el-button class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">
            {{ $t('table.search') }}
          </el-button>
          <el-button class="filter-item" type="primary" icon="el-icon-refresh" @click="resetHandler">
            重置
          </el-button>
        </div>
        <div style="margin-bottom: 10px;">
          <el-button class="filter-item" type="primary" icon="el-icon-edit" @click="openDialog">
            添加
          </el-button>
        </div>

        <!-- 表格 -->
        <el-table :key="tableKey" v-loading="listLoading" :data="list" border fit highlight-current-row style="width: 100%;">
          <el-table-column type="selection" />
          <el-table-column align="center" label="编号">
            <template slot-scope="{row}">
              {{ row.id }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="物料编码">
            <template slot-scope="{row}">
              {{ row.materialEncoding }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="物料名称">
            <template slot-scope="{row}">
              {{ row.materialName }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="型号">
            <template slot-scope="{row}">
              {{ row.version }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="规格">
            <template slot-scope="{row}">
              {{ row.standard }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="单位">
            <template slot-scope="{row}">
              {{ row.unit }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="单价">
            <template slot-scope="{row}">
              {{ row.price }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="类型">
            <template slot-scope="{row}">
              <el-tag size="mini" :type="row.type === 1 ? 'info' : ''">
                {{ row.type === 1 ? '原料' : '成品' }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column align="center" label="备注">
            <template slot-scope="{row}">
              {{ row.remark }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="操作">
            <template slot-scope="{row}">
              <el-button type="primary" icon="el-icon-edit" circle @click="openDialog(row)" />
              <el-button type="danger" icon="el-icon-delete" circle @click="openConfirm(row)" />
            </template>
          </el-table-column>
        </el-table>

        <!-- 分页条 -->
        <pagination v-show="total > 0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.size" @pagination="getList" />

        <!-- 对话框 -->
        <el-dialog :title="dialogTitle" :visible.sync="dialogFormVisible">
          <el-form ref="form" :model="form" :rules="rules">
            <el-form-item v-if="form.id" label="编号" :label-width="formLabelWidth">
              <el-input v-model="form.id" placeholder="编号" :disabled="true" autocomplete="off" />
            </el-form-item>
            <el-form-item label="分类" :label-width="formLabelWidth" prop="categoryId">
              <el-select v-model="form.categoryId" placeholder="选择分类">
                <el-option v-for="item in categoryList" :key="item.id" :label="item.categoryName" :value="item.id" />
              </el-select>
            </el-form-item>
            <el-form-item label="物料编码" :label-width="formLabelWidth" prop="materialEncoding">
              <el-input v-model="form.materialEncoding" placeholder="请输入物料编码" autocomplete="off" />
            </el-form-item>
            <el-form-item label="物料名称" :label-width="formLabelWidth" prop="materialName">
              <el-input v-model="form.materialName" placeholder="请输入物料名称" autocomplete="off" />
            </el-form-item>
            <el-form-item label="型号" :label-width="formLabelWidth" prop="version">
              <el-input v-model="form.version" placeholder="请输入型号" autocomplete="off" />
            </el-form-item>
            <el-form-item label="规格" :label-width="formLabelWidth" prop="standard">
              <el-input v-model="form.standard" placeholder="请输入规格" autocomplete="off" />
            </el-form-item>
            <el-form-item label="单位" :label-width="formLabelWidth" prop="unit">
              <el-input v-model="form.unit" placeholder="请输入单位" autocomplete="off" />
            </el-form-item>
            <el-form-item label="单价" :label-width="formLabelWidth" prop="price">
              <el-input v-model="form.price" placeholder="请输入单价" autocomplete="off" />
            </el-form-item>
            <el-form-item label="类型" :label-width="formLabelWidth" prop="type">
              <el-select v-model="form.type" placeholder="类型">
                <el-option v-for="item in type" :key="item.key" :label="item.label" :value="item.key" />
              </el-select>
            </el-form-item>
            <el-form-item label="备注" :label-width="formLabelWidth" prop="remark">
              <el-input v-model="form.remark" type="textarea" :rows="2" placeholder="请输入备注" />
            </el-form-item>
          </el-form>
          <div slot="footer" class="dialog-footer">
            <el-button @click="dialogFormVisible = false">取 消</el-button>
            <el-button type="primary" @click="submitForm('form')">确 定</el-button>
          </div>
        </el-dialog>
      </el-col>
    </el-row>
  </div>
</template>
<script>
import Pagination from '@/components/Pagination'
import { fetchList, fetchOne, save, edit, remove } from '@/api/material-record'
// as 重新命名
import { fetchList as categoryFetchList } from '@/api/material-category'
export default {
  name: 'MaterialRecord',
  components: { Pagination },
  data() {
    return {
      // 功能标题
      title: '物料档案',
      tableKey: 0,
      listLoading: true,
      // 查询参数
      listQuery: {
        page: 1,
        size: 10,
        materialEncoding: '',
        materialName: '',
        version: '',
        standard: '',
        unit: '',
        price: '',
        type: undefined,
        categoryId: ''
      },
      // 类型
      type: [
        {
          label: '成品',
          key: 0
        },
        {
          label: '原料',
          key: 1
        }
      ],
      // 表格数据
      list: null,
      // 总数
      total: 0,
      // 对话框显示
      dialogFormVisible: false,
      // 对话框宽度
      formLabelWidth: '120px',
      // 表单
      form: {
        id: '',
        materialEncoding: '',
        materialName: '',
        version: '',
        standard: '',
        unit: '',
        price: '',
        type: 0,
        remark: '',
        categoryId: ''
      },
      // 对话框标题
      dialogTitle: '',
      // 校验规则
      rules: {
        materialName: [
          { required: true, message: '请输入物料名称', trigger: 'blur' }
        ],
        categoryId: [
          { required: true, message: '请选择分类', trigger: 'blur' }
        ],
        price: [
          { type: 'number', message: '必须为数值', trigger: 'blur' }
        ]
      },
      // 物料分类数据
      categoryList: null,
      // 物料分类属性菜单
      categoryTree: [],
      defaultProps: {
        children: 'children',
        label: 'categoryName'
      }
    }
  },
  created() {
    this.getList()
    this.getCategoryList()
  },
  methods: {
    /**
     * 查询
     */
    handleFilter() {
      this.getList()
    },
    /**
     * 重置
     */
    resetHandler() {
      this.listQuery = {
        page: 1,
        size: 10,
        materialEncoding: '',
        materialName: '',
        version: '',
        standard: '',
        unit: '',
        price: '',
        type: undefined,
        categoryId: ''
      }
    },
    /**
     * 获取列表
     */
    getList() {
      fetchList(this.listQuery).then(resp => {
        const { data } = resp
        this.total = data.total
        this.list = data.list
      }).finally(() => {
        this.listLoading = false
      })
    },
    /**
     * 获取物料分类数据
     */
    getCategoryList() {
      categoryFetchList({ page: 1, size: 100 }).then(resp => {
        console.log(resp)
        this.categoryList = resp.data.list
        this.categoryTreeHandle(this.categoryList)
      })
    },
    /**
     * 处理分类树
     * @param {Array} categoryList 分类列表
     */
    categoryTreeHandle(categoryList) {
      const map = new Map()
      // 遍历数组存入map
      for (const obj of categoryList) {
        map.set(obj.id, obj)
      }
      // 顶层
      const top = []
      // 遍历map中的所有value
      for (const obj of categoryList) {
        // 根据对应的父级分类id，取得对应的父级分类
        const parent = map.get(obj.parentCategoryId)
        // 存在父级
        if (parent) {
          parent.children ??= []
          parent.children.push(obj)
        } else { // 不存在父级，即，顶层
          top.push(obj)
        }
      }
      this.categoryTree = top
      console.log('categoryTree', this.categoryTree)
    },
    /**
     * 点击树节点触发
     */
    handleNodeClick(data) {
      this.listQuery.categoryId = data.id
      this.getList()
    },
    /**
     * 执行操作 修改和新增
     */
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          if (this.form.id) { // 有 id 就是执行修改，否则执行添加
            this.editHandler()
          } else {
            this.addHandler()
          }
        } else {
          return false
        }
      })
    },
    /**
     * 开启对话框
     * @param {*} row 行数据
     */
    openDialog(row) {
      this.dialogFormVisible = true
      // 开启对话框清空表单数据
      this.form = {
        id: '',
        materialEncoding: '',
        materialName: '',
        version: '',
        standard: '',
        unit: '',
        price: '',
        type: 0,
        remark: '',
        categoryId: ''
      }
      // 清除 rules 原因: 不清除会导致，使用同一个对话框，上一次的规则校验提示还存在
      this.$nextTick(() => {
        this.$refs['form'].clearValidate()
      })
      // 修改
      if (row.id) {
        this.dialogTitle = `修改${this.title}`
        fetchOne(row.id).then(resp => {
          this.form = resp.data
        })
      } else { // 新增
        this.dialogTitle = `添加${this.title}`
      }
    },
    /**
     * 添加
     */
    addHandler() {
      save(this.form).then(resp => {
        this.$notify({
          title: '成功',
          message: resp.msg,
          type: 'success',
          duration: 5000
        })
      }).finally(() => {
        this.dialogFormVisible = false
        this.getList()
      })
    },
    /**
     * 修改
     */
    editHandler() {
      edit(this.form).then(resp => {
        this.$notify({
          title: '成功',
          message: resp.msg,
          type: 'success',
          duration: 5000
        })
      }).finally(() => {
        this.dialogFormVisible = false
        this.getList()
      })
    },
    /**
     * 打开确认框
     * @param {*} row 行数据
     */
    openConfirm(row) {
      const id = row.id
      this.$confirm(`此操作将永久删除编号为 ${id} 的数据`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.deleteHandler(id)
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        })
      })
    },
    /**
     * 删除
     * @param {*} id 行数据
     */
    deleteHandler(id) {
      console.log(id)
      remove([id]).then(resp => {
        console.log(resp)
        this.$notify({
          title: '成功',
          message: resp.msg,
          type: 'success',
          duration: 5000
        })
      }).finally(() => {
        this.getList()
      })
    }
  }
}
</script>
<style scoped>
  .app-container {
    .category-tree {
      text-align: center;
      letter-spacing: 2px;
    }
  }
</style>
